/*
 * main.c
 *
 *  Created on: 20/04/2011
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>

#define MAXINT 2147483647

FILE *fs;
int version_portable = 0; /* 1 para utilizar el algoritmo en assembler */

int euclides(int M, int N, int imprime_mul, int imprime_div)
{
	int divisor, multiplo;

	/* en todos los casos va a utilizar este resultado */
	divisor = mcd(M,N);

	if (imprime_div)
	{
		fprintf (fs, "%d\n", divisor);
	}

	if (imprime_mul)
	{
		multiplo = mcm(M,N);
		fprintf (fs, "%d\n", multiplo);
	}

	return 0;
}

/**
* Abre los archivos a ser procesados mostrando mensaje si ocurre
* algun error. Toma los primeros caracteres e invoca las comparaciones
**/

int process (char* CHAR_M, char* CHAR_N, char *output, int imprime_mul, int imprime_div) {

  int M = atoi(CHAR_M);
  if (M > MAXINT || M < 2) {
    fprintf (stderr, "El primer número ingresado, %d, está fuera del rango [2,MAXINT]\n", M);
    return -1;
  }

  int N = atoi(CHAR_N);
  if (N > MAXINT || N < 2) {
    fprintf (stderr, "El segundo número ingresado, %d, está fuera del rango [2,MAXINT]\n", N);
    return -1;
  }

  if (!output)
    fs = stdout;
  else {
    fs = fopen (output, "w");
    if (!fs) {
      fprintf (stderr, "Error al abrir el archivo %s\n", output);
      return -1;
    }
  }

  euclides(M, N, imprime_mul, imprime_div);

  fclose (fs);
  return 0;
}


void imprime_version () {
  printf ("\ncommon - version: 1.0\n\n");
}

void imprime_uso () {
  printf ("\n   Usage:\n"
	  "         common -h\n"
	  "         common -v\n"
	  "         common [options] M N\n"
	  "   Options:\n"
	  "         -h, --help         Print usage information.\n"
	  "         -v, --version      Print version information.\n"
	  "         -o, --output       Path to output file.\n"
	  "         -d, --divisor      Just the divisor.\n"
	  "         -m, --multiple     Just the multiple.\n"
	  "   Examples:\n"
	  "         common -o - 256 192\n\n");
}

int main (int argc, char *argv[]) {
  int c;
  int imprime_mul = 0;
  int imprime_div = 0;
  char *output_file = NULL;
  int solo_texto=0;

  while (1) {
    static struct option long_options[] = {
      {"version", no_argument, 0, 'v'},
      {"help", no_argument, 0, 'h'},
      {"divisor", required_argument, 0, 'd'},
      {"multiple", required_argument, 0, 'm'},
      {"output", required_argument, 0, 'o'},
      {0, 0, 0, 0}
    };
    int option_index = 0;
    c = getopt_long (argc, argv, "vho:dm", long_options, &option_index);

    if (c == -1)
      break;

    switch (c) {
    case 'v':
      imprime_version ();
			solo_texto=1;
      break;

    case 'h':
      imprime_uso ();
			solo_texto=1;
      break;

    case 'o':
      output_file = optarg;
      break;

    case 'd':
      imprime_div = 1;
      break;

    case 'm':
      imprime_mul = 1;
      break;

    case '?':
      fprintf (stderr, "Error en los parámetros\n");
      return -1;
      break;

    default:
      abort ();
    }
  }

	/* Accion por default cuando no hay opcion: calcula ambos valores*/
	if (optind == 1) {
		imprime_mul = 1;
		imprime_div = 1;
	}
  if (optind < argc) {
			if ((optind > (argc-2)) && (!solo_texto)) {
				fprintf(stderr, "Faltan parámetros\n");
				return -1;
			}
		  if (!solo_texto)	
    		process (argv[optind], argv[optind + 1], output_file, imprime_mul, imprime_div);
  } else {
		if (!solo_texto)
			fprintf (stderr, "Debe específicar los numeros de entrada\n");
	}
  return 0;
}
